package server.auction;

/**
 * This class represents a server of an auction service.
 * For accepting requests from clients a new thread is beeing created.
 * Each client is handled in an own thread. Server and client communicate
 * over a tcp-socket in another own thread. The server also notificate the client
 * over a UDP-datagramsocket in an own thread.
 * With the user-input "Enter-Key" the server shuts down.
 *
 * @version 1.0 vom 13.10.2012
 * @author Peter Tillian 1026312
 */

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.IOException;
import java.rmi.RemoteException;
import java.security.PrivateKey;

import security.SecureHelper;

public class AuctionServer {
	public static void main(String[] args) {
		checkArguments(args);

		BufferedReader inReader = new BufferedReader(new InputStreamReader(
				System.in));

		// get arguments
		int serverPort = Integer.parseInt(args[0]);
		String analyticsName = args[1];
		String billingName = args[2];
		String serverKey = args[3];
		String clientKeyDir = args[4];

		// Read properties from registry.properties
		int registryPort = -1;
		String registryHost = "";
		java.io.InputStream is = ClassLoader
				.getSystemResourceAsStream("registry.properties");
		if (is != null) {
			java.util.Properties props = new java.util.Properties();
			try {
				props.load(is);
				registryPort = Integer.parseInt(props
						.getProperty("registry.port"));
				registryHost = props.getProperty("registry.host");
			} catch (IOException e) {
				System.err.println("ERROR: Reading from registry.properties:"
						+ e.getMessage());
			} catch (NumberFormatException e) {
				System.err
						.println("ERROR: Values in registry.properties file are no integers!");
			} finally {
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		} else {
			System.err.println("Properties file not found!");
		}

		// get private key of the server
		PrivateKey privateKey = null;
		try {
			privateKey = SecureHelper.getPrivateKey(serverKey);
		} catch (FileNotFoundException e) {
			System.err.println("You have no private key!");
			System.exit(1);
		} catch (IOException e) {
			System.err.println("Wrong password!");
			System.exit(1);
		}

		// Start new thread that accepts tcp-connections with clients.
		AuctionServerAcceptConnectionsThread acceptThread = new AuctionServerAcceptConnectionsThread(
				serverPort, analyticsName, billingName, privateKey,
				clientKeyDir, registryHost, registryPort);
		acceptThread.start();
		System.out.println("Server online.");

		try { // wait until the user enters "!exit"
			String userInput = "";
			while ((userInput = inReader.readLine()) != null) {
				if (userInput.equals("!exit")) {
					break;
				}
			}
		} catch (IOException e) {
			System.err.println("Error reading from stdin: " + e.getMessage());
			System.exit(1);
		}

		// interrupt ServerAcceptConnectionsThread which closes that socket.
		acceptThread.interrupt();

		// free ressources, close registry
		try {
			inReader.close();
		} catch (RemoteException e) {
			System.err.println("ERROR: Closing RMI-Registry:" + e.getMessage());
		} catch (IOException e) {
			System.err.println("Error closing reader from stdin: "
					+ e.getMessage());
		}

		System.out.println("Server shut down successfully!");
	} // end of main

	/**
	 * This method checks the input arguments. It must be one arguments and
	 * numeric.
	 */
	private static void checkArguments(String[] args) {
		if (args.length != 5) {
			System.err
					.println("Usage: server <port> <analytics_binding> <billing_binding> <server.key> <clients.key.dir>");
			System.exit(1);
		}
		try {
			Integer.parseInt(args[0]);
		} catch (NumberFormatException e) {
			System.err
					.println("Usage: server <port> <analytics_binding> <billing_binding> <server.key> <clients.key.dir>");
			System.err.println("<port> must be numeric");
			System.exit(1);
		}
	}
} // end of class Server
